#!/usr/bin/perl -w

package Resultados;
use Exporter;
@ISA = ('Exporter');
@EXPORT = ('rSeleccionarFiltros', 'rMostrarResultados');


# Tiro esto para dar facha. No entiendo bien como va 
# el tema de los directorios (?)
$CONFDIR = "./CONFDIR/";
$MAEDIR = "./MAEDIR/";
$PROCDIR = "./PROCDIR/";
$ARCHCONF = $CONFDIR . "InstalaW5.conf";
$ARCHPAT = $MAEDIR . "patrones";


# **********************************************************
# Funciones auxiliares de la resolución de consultas
# relacionadas a los resultados detallados.
# **********************************************************

# Crea un hash con la información de los patrones por ID.
# CREA: %patrones con $patrones{PAT_ID} = EXPREG
sub rCrearHashDePatrones(){
	# Verifica la existencia del archivo de patrones.
	if(-e $ARCHPAT){
		open(PATRONES, "< $ARCHPAT") or die 
			"No se pudo abrir archivo de patrones.\n"
	}

	# Agrega los pares padrón / ID al hash patID.	
	while(my $linea = <PATRONES>){
		$linea =~ /(.*),'(.*)',.*,.*\n/;
		$patrones{$1} = $2;
	}
	close(PATRONES);
}


# Crea un hash con los nombres de todos los archivos procesados.
# CREA: %archivos.
sub rCrearHashDeArchivos(){
	opendir(PROCDIR, $PROCDIR) or die
		"No se pudo abrir directorio de archivos procesados.\n";
	my @archivo = readdir(PROCDIR);
	foreach (@archivo){ 
		# Ignoro archivos que son resultados.
		if($_ !~ /.*\..*/){
			$archivos{$_} = "";
		}
	}
	close(PROCDIR);
}


# Busca en ARCHCONF el registro SECUENCIA2, que es la que indica
# el número de último ciclo.
# CREA $ultimoCiclo.
sub rObtenerUltimoCiclo(){
	# Verifica la existencia del archivo de configuración.
	if(-e $ARCHCONF){
		open(CONFIG, "< $ARCHCONF") or die
			"No se pudo abrir archivo de configuraciones.\n"
	}

	# Busca el registro SECUENCIA2 que almacena el último ciclo. 
	while(my $linea = <CONFIG>){
		if($linea =~ /^SECUENCIA2=(.*)$/){
			$ultimoCiclo = $1;
		}
	}
	close(CONFIG);
}

# Guía al usuario en el ingreso de patrones para filtrar
# los resultados. Almacena en el hash %f_patrones los 
# patrones seleccionados para filtrar.
# USA: $p, %patrones.
# CREA: %f_patrones.
sub rFiltrarPorPatron(){
	rCrearHashDePatrones();
	
	# Si el modo de filtado es por patrón, sólo se permite elegir uno.
	if($rmodo eq "p"){
		my $selValida = 0;
		while(!$selValida){
			print("Ingrese un patrón: \n");
			chomp(my $patron = <STDIN>);
			if(not exists $patrones{$patron}){
				print("Patrón especificado inválido. Seleccione nuevamente.\n");
			}
			else{
				$f_patrones{$patron} = $patrones{$patron};
				$selValida = 1;
			}
		}
	}

	# En los otros dos modos se pueden elegir más de un patrón.
	else{
		my $finDeIngreso = 0;
		print("Ingrese patrones, por número, para filtrar, 0 para terminar.\n");
		while(!$finDeIngreso){
			chomp(my $patron = <STDIN>);
			if($patron == 0){
				$finDeIngreso = 1;
			}	
			elsif(not exists $patrones{$patron}){
				print("Patrón especificado inválido. Seleccione nuevamente.\n");
			}
			else{
				$f_patrones{$patron} = $patrones{$patron};
			}
		}
	}
}


# Guía al usuario en el ingreso de nombres de archivo para 
# filtrar los resultados. Almacena en el hash %f_archivos 
# los archivos seleccionados para filtrar.
# USA: $a, %archivos.
# CREA: %f_archivos.
sub rFiltrarPorArchivo(){
	rCrearHashDeArchivos();
	
	# Si el modo de filtado es por archivo, sólo se permite elegir uno.
	if($rmodo eq "a"){
		my $selValida = 0;
		while(!$selValida){
			print("Ingrese un archivo: \n");
			chomp(my $archivo = <STDIN>);
			if(not exists $archivos{$archivo}){
				print("Archivo especificado inválido. Seleccione nuevamente.\n");
			}
			else{
				$f_archivos{$archivo} = "";
				$selValida = 1;
			}
		}
	}
	
	# En los otros dos modos se pueden elegir más de un patrón.
	else{
		my $finDeIngreso = 0;
		print("Ingrese nombres de archivo para filtrar, entrar para terminar.\n");
		while(!$finDeIngreso){
			chomp(my $archivo = <STDIN>);
			if($archivo eq ""){
				$finDeIngreso = 1;
			}	
			elsif(not exists $archivos{$archivo}){
				print("Archivo especificado inválido. Seleccione nuevamente.\n");
			}
			else{
				$f_archivos{$archivo} = "";
			}
		}
	}
}

# Guía al usuario en el ingreso de números de ciclo para 
# filtrar los resultados. Almacena en el hash %f_ciclos 
# los archivos seleccionados para filtrar.
# USA: $c, $ultimoCiclo.
# CREA: %f_ciclos.
sub rFiltrarPorCiclo(){
	rObtenerUltimoCiclo();
	
	# Si el modo de filtado es por ciclo, sólo se permite elegir uno.
	if($rmodo eq "c"){
		my $selValida = 0;
		while(!$selValida){
			print("Ingrese un ciclo: \n");
			chomp(my $ciclo = <STDIN>);
			if($ciclo >= $ultimoCiclo){
				print("Ciclo especificado inválido. Seleccione nuevamente.\n");
			}
			else{
				$f_ciclos{$ciclo} = "";
				$selValida = 1;
			}
		}
	}
	
	# En los otros dos modos se pueden elegir más de un ciclo.
	else{
		my $finDeIngreso = 0;
		print("Ingrese números de ciclo para filtrar, 0 para terminar.\n");
		while(!$finDeIngreso){
			chomp(my $ciclo = <STDIN>);
			if($ciclo =~ /^[0-9]+$/){
				if($ciclo == 0){
					$finDeIngreso = 1;
				}	
				elsif($ciclo >= $ultimoCiclo){
					print("Ciclo especificado inválido. Seleccione nuevamente.\n");
				}
				else{
					$f_ciclos{$ciclo} = "";
				}
			}
			else{
				print("Ciclo especificado inválido. Seleccione nuevamente.\n");
			}
		}
	}
}


# Imprimen por pantalla los resultados.
# USA: $x, $f_patrones, $f_ciclos, $f_archivos.
sub rMostrarResultados($){
	print("W-FIVE: SISTEMA DE CONSULTAS \n");
	print("Consulta 42 \n");
	# TODO listar patrones usados.
 
	my @listaDePatrones = keys(%f_patrones);
	foreach(@listaDePatrones){
		my $resultados = $PROCDIR . "resultados." . $_;
		if(-e $resultados){
			open(RESULTADOS, "< $resultados") or die 
				"No se pudo abrir archivo de resultados.\n"
		}
		else{
			next;
		}
			
		print("$resultados");
	
		# Puede que el registro sea de varias líneas, sin embargo la primera
		# es siempre de la forma PAT_ID+-#-+NOMARCHIVO+-#-+NREG+-#-+RESULTADO
		# La variable lineaNueva se activa cuando se encuentra un registro que
		# cumple todas las condiciones pedidas y se puede extender.
		my $lineaNueva = 0;
		while(my $linea = <RESULTADOS>){
			if($linea =~ /^([0-9]+)\+-#-\+(.+)\+-#-\+[0-9]+\+-#-\+(.+)$/){
				if((exists $f_ciclos{$1}) && (exists $f_archivos{$2})){
					printf("$3 \n");
					$lineaNueva = 1;
				}
				else{
					$lineaNueva = 0;
				}
			}
			elsif($lineaNueva){
				print("$linea");
			}
		}	
		close(RESULTADOS);
	}

}



# Ejecutado sólo si el usuario invoca a la aplicación con la opción -r.
# Guía al usuario en el ingreso de filtros para listar los resultados 
# de los archivos de resultados detallados "resultados.PAT_ID".
# CREA: $p, $c, $a.
sub rSeleccionarFiltros(){
	# Itera hasta que el usuario seleccione una opción válida.
	my $selvalida = 0;
	
	print("Seleccione p para listar por patrón; \n");
	print("seleccione c para listar por ciclo; \n");
	print("seleccione a para listar por archivo; \n");
	print("seleccione s para salir. \n");

	while(!$selvalida){
		print("Ingrese una opción: [p, c, a, s] \n");
		chomp($rmodo = <STDIN>);
	
		if($rmodo eq "p"){
			$selvalida = 1;
			rFiltrarPorPatron();
			rFiltrarPorCiclo();
			rFiltrarPorArchivo();
		}
		
		elsif($rmodo eq "c"){
			$selvalida = 1;	
			rFiltrarPorCiclo();
			rFiltrarPorPatron();
			rFiltrarPorArchivo();
		}
		
		elsif($rmodo eq "a"){
			$selvalida = 1;
			rFiltrarPorArchivo();
			rFiltrarPorPatron();
		}

		elsif($rmodo eq "s"){
			exit 0;
		}
	
		else{
			print("Selección inválida, intente nuevamente.\n");
		}
	}
}
